package http

import (
    . "nightowl/auth"
    . "nightowl/config"
    "nightowl/logger"
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "time"
    "net/url"
    "strings"
    "strconv"
)
const (
	HTTP_METHOD_GET = "GET"
	HTTP_METHOD_POST = "POST"
	HTTP_METHOD_PUT = "PUT"
	HTTP_METHOD_DELETE = "DELETE"


	POST_JSON_CONTENT_TYPE = "application/json"
)
type RequestParams struct{
    Url string
    Method string
    PathVars map[string] interface{}
    Params map[string] interface{}
    Headers map[string]string
}

func BuildUrl(urlstr string, pathVars , queryParams map[string] interface{}) string{
    requestUrl := urlstr
    if pathVars != nil{
        for k, v := range pathVars{

            requestUrl = strings.Replace(requestUrl, "{"+k+"}", v.(string), -1)
        }
    }
    if queryParams != nil{
        params := url.Values{}
        for k, v := range queryParams{
            params.Add(k, v.(string))
        }
        requestUrl = requestUrl + "?" + params.Encode()
    }
    return requestUrl
}
func Request(reqParams RequestParams){
	client := &http.Client{
        Timeout: 10 * time.Second, // 设置超时时间
    }
    queryParams := map[string] interface{}{}
    method := reqParams.Method
    if method == HTTP_METHOD_GET && reqParams.Params != nil{
        queryParams = reqParams.Params
    }
    requestUrl := BuildUrl(reqParams.Url, reqParams.PathVars, queryParams)
    // fmt.Println("requestUrl:", requestUrl)

    requestBody := []byte{} 
    if method != HTTP_METHOD_GET && 
        reqParams.Headers != nil && 
        reqParams.Headers["content-type"] == POST_JSON_CONTENT_TYPE && 
        reqParams.Params != nil{
        // fmt.Println(method, "params:", reqParams.Params)
    	requestBody, _ = json.Marshal(reqParams.Params)
    }
    /***********添加Sign***********/
    timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
    // fmt.Println("timestamp:", timestamp)

    signData := BuildSignStr(timestamp, method, requestUrl, string(requestBody))
    // fmt.Println("signData:", signData)
    sign := Sign(signData)
    // fmt.Println("sign:", sign)
    req, err := http.NewRequest(
        method,
        requestUrl,
        bytes.NewBuffer(requestBody),
    )
    if err != nil {
        logger.Error("Request|http.NewRequest|error:%s", err)
        return
    }
    req.Header.Add(SIGN_AK_HEADER_NAME, ENV_CONFIG.AuthConfig.AccessKey)
    req.Header.Add(SIGN_TIMESTAMP_HEADER_NAME, timestamp)
    req.Header.Add(SIGN_SIGN_HEADER_NAME, sign)
    /***********添加Sign END***********/

    // 设置请求头
    if reqParams.Headers != nil{    	
    	for k, v := range reqParams.Headers{
    		req.Header.Add(k, v)
    	}
    }

    resp, err := client.Do(req)
    if err != nil {
        logger.Error("Request|client.Do|error:%s", err)
        return
    }
    defer resp.Body.Close()

    // io.ReadAll(resp.Body)
    resonseBody, err := io.ReadAll(resp.Body)
    if err != nil {
        logger.Error("Request|io.ReadAll|error:%s", err)
        return
    }
    if logger.Level >= logger.DEBUG_LEVEL{
        logger.Debug("Request|status: %d|content: %s", resp.StatusCode, string(resonseBody))
    }
}